package nu.zoom.swing.desktop.workbench;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dialog.ModalityType;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.SwingUtilities;

import nu.zoom.swing.desktop.ErrorReporter;
import nu.zoom.swing.desktop.Workbench;

import org.ops4j.gaderian.Messages;

/**
 * @version $Revision: 1.1 $
 * @author $Author: johan $
 */
public class ErrorReporterImpl implements ErrorReporter {
    private Workbench workbench;
    private Messages messages;

    public ErrorReporterImpl(Workbench workbench, Messages messages) {
        this.workbench = workbench;
        this.messages = messages;
    }

    @Override
    public void reportError(Exception e) {
        showErrorDialog(null, e);
    }

    @Override
    public void reportError(String message) {
        showErrorDialog(message, null);
    }

    @Override
    public void reportError(String message, Exception e) {
        showErrorDialog(message, e);
    }

    private void showErrorDialog(final String message, final Exception e) {
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                final JDialog errorDialog = new JDialog(workbench.getDialogOwner());
                errorDialog.getContentPane().setLayout(new BorderLayout());
                String errorDialogTitleString = "Error";
                errorDialogTitleString = messages.getMessage("window.title.errorreporter");
                errorDialog.setTitle(errorDialogTitleString);

                String closeString = "Close";
                closeString = messages.getMessage("button.close");

                JButton closeButton = new JButton(closeString);
                closeButton.addActionListener(new ActionListener() {

                    @Override
                    public void actionPerformed(ActionEvent e) {
                        errorDialog.dispose();
                    }
                });

                JPanel buttonPane = new JPanel();
                buttonPane.add(closeButton);

                errorDialog.getContentPane().add(buttonPane, BorderLayout.SOUTH);

                String errorMessageString;
                if (message == null) {
                    if (e != null) {
                        errorMessageString = e.getLocalizedMessage();
                    } else {
                        errorMessageString = "";
                    }
                } else {
                    errorMessageString = message;
                }
                JLabel errorMessage = new JLabel(errorMessageString);
                Font stderrorFont = errorMessage.getFont();
                Font errorFont = stderrorFont.deriveFont(Font.BOLD);
                errorMessage.setFont(errorFont);
                errorMessage.setForeground(Color.RED);
                errorDialog.getContentPane().add(errorMessage, BorderLayout.NORTH);

                if (e != null) {
                    StringBuffer traceBuffer = new StringBuffer();
                    traceBuffer.append(e.toString());
                    traceBuffer.append("\n-----------------\n");
                    StackTraceElement[] trace = e.getStackTrace();
                    for (int i = 0; i < trace.length; i++) {
                        traceBuffer.append(trace[i].toString());
                        traceBuffer.append("\n");
                    }
                    JTextArea traceArea = new JTextArea(traceBuffer.toString(), 10, 80);
                    traceArea.setEditable(false);

                    errorDialog.getContentPane().add(new JScrollPane(traceArea),
                            BorderLayout.CENTER);
                }
                errorDialog.pack();
                errorDialog.setLocationRelativeTo(workbench.getDialogOwner());
                errorDialog.setModalityType(ModalityType.APPLICATION_MODAL);
                errorDialog.setVisible(true);
            }
        });
    }
}
